package com.csproj.system.resource;

import com.codahale.metrics.annotation.Timed;
import com.csproj.example.service.OrganizationService;
import com.csproj.example.service.dto.OrganizationDTO;
import com.csproj.siiat.base.common.dto.BaseDTO;
import com.csproj.siiat.base.common.repository.PageableTools;
import com.csproj.siiat.security.jwt.JWTConfigurer;
import com.csproj.siiat.security.jwt.TokenProvider;
import com.csproj.system.resource.vm.LoginVM;
import com.csproj.system.service.SysLogsService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Pageable;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.encoding.PasswordEncoder;
import org.springframework.security.authentication.encoding.PlaintextPasswordEncoder;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.net.URISyntaxException;
import java.time.Clock;
import java.time.ZonedDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/siiat/v1")
public class LoginResource {

    private final Logger log = LoggerFactory.getLogger(LoginResource.class);

    private final TokenProvider tokenProvider;

    private final AuthenticationManager authenticationManager;

    private final SysLogsService sysLogsService;
    private PasswordEncoder passwordEncoder;

//    public LoginResource(TokenProvider tokenProvider,
//                         AuthenticationManager authenticationManager,
//                         PasswordEncoder passwordEncoder) {
//        this.tokenProvider = tokenProvider;
//        this.authenticationManager = authenticationManager;
//        this.passwordEncoder = passwordEncoder;
//    }
    public LoginResource(TokenProvider tokenProvider,
                         AuthenticationManager authenticationManager,
                         SysLogsService sysLogsService){
        this.tokenProvider = tokenProvider;
        this.authenticationManager = authenticationManager;
        passwordEncoder = new PlaintextPasswordEncoder();
        this.sysLogsService = sysLogsService;
    }
    /**
     * GET  /login : 登录.
     * @return 返回授权
     */
    @PostMapping("/login")
    @Timed
    public BaseDTO login(@Valid @RequestBody LoginVM loginVM, HttpServletResponse response) {


        System.out.println("admin=="+new BCryptPasswordEncoder().encode("admin"));

        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(loginVM.getUsername(), loginVM.getPassword());
        try {
            Authentication authentication = this.authenticationManager.authenticate(authenticationToken);
            SecurityContextHolder.getContext().setAuthentication(authentication);
            boolean rememberMe = (loginVM.isRememberMe() == null) ? false : loginVM.isRememberMe();
            String jwt = tokenProvider.createToken(authentication, rememberMe);
            response.addHeader(JWTConfigurer.AUTHORIZATION_HEADER, "Bearer " + jwt);
            Map<String, Object> result = new HashMap<String, Object>();

            //result.put("tokenId", "Bearer " + jwt);
            result.put("tokenId", jwt);
            Clock clock = Clock.systemDefaultZone();
            result.put("loginTime", clock.millis());
            ZonedDateTime dateTime = ZonedDateTime.now().plusDays(4 * 7);
            //result.put("failureTime", DateUtils.getDateLong(dateTime));

            this.sysLogsService.saveForPost("",loginVM.getUsername()+":user_login_success","user_login");
            return BaseDTO.createBaseDTO().setData(result);
        } catch (AuthenticationException ae) {
            if (ae.getLocalizedMessage() != null) {
                if ("Bad credentials".equals(ae.getLocalizedMessage())) {
                    this.sysLogsService.saveForPost("",loginVM.getUsername()+":user_login_failed","user_login");
                    return BaseDTO.createBaseDTO().setSuccess(false).setMessage("user_no_exist_or_pwd_error");
                }
                if("unactivated".equals(ae.getLocalizedMessage())){
                    this.sysLogsService.saveForPost("",loginVM.getUsername()+":user_login_failed","user_login");
                    return BaseDTO.createBaseDTO().setSuccess(false).setMessage("user_disabled");
                }
            } else {
                this.sysLogsService.saveForPost("",loginVM.getUsername()+":user_login_failed","user_login");
                return BaseDTO.createBaseDTO().setSuccess(false).setMessage("user_no_exist_or_pwd_error");
            }
            this.sysLogsService.saveForPost("",loginVM.getUsername()+":user_login_failed","user_login");
            return BaseDTO.createBaseDTO().setSuccess(false).setMessage("login_failed");
        }
    }
}
